﻿//#include "stdafx.h"
#include "SysCtrl.h"

#include <QtGui/QWindow>
#include <QtCore/QDebug>
#include <sstream>

#include "CommandProcess/CommandProcess.h"


SysCtrl::SysCtrl()
{
	
}

SysCtrl::~SysCtrl()
{
}


SysCtrl& SysCtrl::Instance()
{
	static SysCtrl instance;
	return instance;
}

#include "windows.h"

bool SysCtrl::KExitWindowsEx(unsigned int uFlags)
{
	if (!GetShutdownPrivilege())
	{
		return false;
	}
	// 强制关闭计算机
	//if (!ExitWindowsEx(EWX_SHUTDOWN/* | EWX_FORCE*/, 0))
	//if (!ExitWindowsEx(EWX_LOGOFF/* | EWX_FORCE*/, 0))
	if (!ExitWindowsEx(uFlags, 0))
	{
		return false;
	}
	return true;
}

bool SysCtrl::GetShutdownPrivilege()
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp;
	//获取进程标志
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
	{
		return false;
	}
	//获取关机特权的LUID
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	//获取这个进程的关机特权
	AdjustTokenPrivileges(hToken, false, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
	if (GetLastError() != ERROR_SUCCESS)
	{
		return false;
	}
	return true;
}

bool SysCtrl::SysCmd(QString cmd)
{
	if (!GetShutdownPrivilege())
	{
		return false;
	}

	QByteArray stdOutResult;
	QByteArray stdErrResult;
	int exitCode = 0;
	QStringList arguments;
	arguments << "/c";
	arguments << cmd;
	bool bRes = CommandProcess::StaticExecuteProgramWaitResult("cmd.exe", arguments, stdOutResult, stdErrResult, exitCode, 30000);

	return bRes;
}

bool SysCtrl::SysShutdown(bool bForce)
{
	return KExitWindowsEx(EWX_HYBRID_SHUTDOWN | (bForce ? EWX_FORCE : 0));
}

bool SysCtrl::SysShutdownCmd(bool bForce)
{
	QString cmd = "shutdown /s /t 3";
	if (bForce)
	{
		cmd += " /p /f";
	}
	return SysCmd(cmd);
}

bool SysCtrl::SysReboot(bool bForce)
{
	return KExitWindowsEx(EWX_REBOOT | (bForce ? EWX_FORCE : 0));
}

bool SysCtrl::SysRebootCmd(bool bForce)
{
	QString cmd = "shutdown /r /t 3";
	if (bForce)
	{
		cmd += " /p /f";
	}
	return SysCmd(cmd);
}

bool SysCtrl::SysLogoff(bool bForce)
{
	return KExitWindowsEx(EWX_LOGOFF | (bForce ? EWX_FORCE : 0));
}

bool SysCtrl::SysLogoffCmd(bool bForce)
{
#if 1
	QString cmd = "shutdown /l /t 3";
	if (bForce)
	{
		cmd += " /p /f";
	}
	return SysCmd(cmd);
#else
	int iRes = system("logout");
	//int iRes = CommandProcess::StaticExecuteProgram("cmd.exe /c logoff", QStringList());
	return (iRes != 0 ? false : true);
#endif
}

bool SysCtrl::SysLock()
{
	// rundll32.exe user32.dll,LockWorkStation

	int iRes = CommandProcess::StaticExecuteProgram("rundll32.exe", QStringList() << "user32.dll,LockWorkStation");
	return (iRes != 0 ? false : true);
}

#include <powrprof.h>
#pragma comment(lib, "PowrProf.lib")
bool SysCtrl::SysSuspend(bool bHibernate, bool bForce)
{
	if (!GetShutdownPrivilege())
	{
		return false;
	}
	// win7使用函数 BOOL SetSystemPowerState(BOOL fSuspend, BOOL fForce);
	// visita使用函数 BOOLEAN SetSuspendState(_In_ BOOLEAN bHibernate, _In_ BOOLEAN bForce, _In_ BOOLEAN bWakeupEventsDisabled);
	return ::SetSuspendState(bHibernate, bForce, false);
}

bool SysCtrl::KeyBoardEvent(std::vector<int> keyVec)
{
	//keybd_event()
	//mouse_event()

	// 按下
	for (unsigned int i = 0; i < keyVec.size(); ++i)
	{
		keybd_event(keyVec[i], 0, 0, 0);
	}
	Sleep(1);
	// 弹起
	for (int i = static_cast<int>(keyVec.size() - 1); i >= 0; --i)
	{
		keybd_event(keyVec[i], 0, KEYEVENTF_KEYUP, 0);
	}
	return true;
}

bool SysCtrl::KeyBoardSendInput(std::vector<int> keyVec)
{
	// 按下
	for (unsigned int i = 0; i < keyVec.size(); ++i)
	{
		INPUT input;
		input.type = INPUT_KEYBOARD;
		input.ki.wVk = keyVec[i];
		input.ki.wScan = 0;
		input.ki.dwFlags = 0;
		input.ki.time = 0;
		input.ki.dwExtraInfo = 0;
		SendInput(1, &input, sizeof(INPUT));
	}
	Sleep(1);
	// 弹起
	for (int i = static_cast<int>(keyVec.size() - 1); i >= 0; --i)
	{
		INPUT input;
		input.type = INPUT_KEYBOARD;
		input.ki.wVk = keyVec[i];
		input.ki.wScan = 0;
		input.ki.dwFlags = KEYEVENTF_KEYUP;
		input.ki.time = 0;
		input.ki.dwExtraInfo = 0;
		SendInput(1, &input, sizeof(INPUT));
	}
	return true;
}

bool SysCtrl::KeyBoardPostMessage(std::vector<int> keyVec)
{
	// 获取系统当前的前端窗口
	HWND hWnd = ::GetForegroundWindow();
	if (!hWnd)
	{
		return false;
	}
	// 按下
	for (int i = 0; i < keyVec.size(); ++i)
	{
		if (!::PostMessage(hWnd, WM_KEYDOWN, keyVec[i], 1))
		{
			//return false;
		}
		Sleep(10);
	}
	//Sleep(1);
	// 弹起
	for (int i = static_cast<int>(keyVec.size() - 1); i >= 0; --i)
	{
		if (!::PostMessage(hWnd, WM_KEYUP, keyVec[i], 1))
		{
			//return false;
		}
		Sleep(10);
	}
	return true;
}

bool SysCtrl::KeyBoardForegroundWindow(QString strKeys)
{
	std::vector<int> keyVec = SysCtrl::ParseKeys(strKeys);
	if (keyVec.empty())
	{
		return false;
	}
	return KeyBoardEvent(keyVec);
}

std::vector<int> SysCtrl::ParseKeys(QString strKeys)
{
	QStringList strKeyList;
	strKeys = strKeys.trimmed();
	strKeys = strKeys.replace(' ', "");
	strKeys = strKeys.replace('\t', "");
	strKeys = strKeys.replace('\r', "");
	strKeys = strKeys.replace('\n', "");
	int posPlus = -1;
	while (!strKeys.isEmpty())
	{
		if (strKeys[0] == '+')
		{// 对加号特殊处理
			strKeyList << "+";
			strKeys = strKeys.mid(1);
			continue;
		}
		// 查找加号分割符
		posPlus = strKeys.indexOf('+');
		if (-1 == posPlus)
		{
			strKeyList << strKeys;
			break;
		}
		else
		{
			strKeyList << strKeys.left(posPlus);
			strKeys = strKeys.mid(posPlus + 1);
		}
	}
	qDebug() << strKeyList;
	std::vector<int> keysVec;
	for (size_t i = 0; i < strKeyList.size(); ++i)
	{
		QString strKey = strKeyList[i];
		if (strKey.size() != 1)
		{// 转成大写
			strKey = strKey.toUpper();
		}
		if (!GetKeyVal(strKey, keysVec))
		{
			return std::vector<int>();
		}
	}

	return keysVec;
}


void SysCtrl::InitKeyValMap()
{
	// 虚拟按键对应表
	// https://docs.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes

	if (!mKeyValMap.empty())
	{
		return;
	}
	mKeyValMap["LBUTTON"].push_back(VK_LBUTTON);// 0x01;		//Left mouse button
	mKeyValMap["RBUTTON"].push_back(VK_RBUTTON);// 0x02;		//Right mouse button
	mKeyValMap["CANCEL"].push_back(VK_CANCEL);// 0x03;		//Control - break processing
	mKeyValMap["MBUTTON"].push_back(VK_MBUTTON);// 0x04;		//Middle mouse button(three - button mouse)
	mKeyValMap["XBUTTON1"].push_back(VK_XBUTTON1);// 0x05;		//X1 mouse button
	mKeyValMap["XBUTTON2"].push_back(VK_XBUTTON2);// 0x06;		//X2 mouse button
	mKeyValMap["BACK"].push_back(VK_BACK);// 0x08;		//BACKSPACE key
	mKeyValMap["TAB"].push_back(VK_TAB);// 0x09;		//TAB key
	mKeyValMap["CLEAR"].push_back(VK_CLEAR);// 0x0C;		//CLEAR key
	mKeyValMap["RETURN"].push_back(VK_RETURN);// 0x0D;		//ENTER key
	mKeyValMap["SHIFT"].push_back(VK_SHIFT);// 0x10;		//SHIFT key
	mKeyValMap["CONTROL"].push_back(VK_CONTROL);// 0x11;		//CTRL key
	mKeyValMap["CTRL"].push_back(VK_CONTROL);// 0x11;
	mKeyValMap["MENU"].push_back(VK_MENU);// 0x12;		//ALT key
	mKeyValMap["ALT"].push_back(VK_MENU);// 0x12;
	mKeyValMap["PAUSE"].push_back(VK_PAUSE);// 0x13;		//PAUSE key
	mKeyValMap["CAPITAL"].push_back(VK_CAPITAL);// 0x14;		//CAPS LOCK key
	mKeyValMap["KANA"].push_back(VK_KANA);// 0x15;		//IME Kana mode
	mKeyValMap["HANGUEL"].push_back(VK_HANGUL);// 0x15;		//IME Hanguel mode(maintained for compatibility; use VK_HANGUL)
	mKeyValMap["HANGUL"].push_back(VK_HANGUL);// 0x15;		//IME Hangul mode
	mKeyValMap["JUNJA"].push_back(VK_JUNJA);// 0x17;		//IME Junja mode
	mKeyValMap["FINAL"].push_back(VK_FINAL);// 0x18;		//IME final mode
	mKeyValMap["HANJA"].push_back(VK_HANJA);// 0x19;		//IME Hanja mode
	mKeyValMap["KANJI"].push_back(VK_KANJI);// 0x19;		//IME Kanji mode
	mKeyValMap["ESCAPE"].push_back(VK_ESCAPE);// 0x1B;		//ESC key
	mKeyValMap["ESC"].push_back(VK_ESCAPE);// 0x1B;
	mKeyValMap["CONVERT"].push_back(VK_CONVERT);// 0x1C;		//IME convert
	mKeyValMap["NONCONVERT"].push_back(VK_NONCONVERT);// 0x1D;		//IME nonconvert
	mKeyValMap["ACCEPT"].push_back(VK_ACCEPT);// 0x1E;		//IME accept
	mKeyValMap["MODECHANGE"].push_back(VK_MODECHANGE);// 0x1F;		//IME mode change request

	mKeyValMap["SPACE"].push_back(VK_SPACE);// 0x20;		//SPACEBAR
	
	mKeyValMap["PRIOR"].push_back(VK_PRIOR);// 0x21;		//PAGE UP key
	mKeyValMap["NEXT"].push_back(VK_NEXT);// 0x22;		//PAGE DOWN key
	mKeyValMap["END"].push_back(VK_END);// 0x23;		//END key
	mKeyValMap["HOME"].push_back(VK_HOME);// 0x24;		//HOME key

	mKeyValMap["LEFT"].push_back(VK_LEFT);// 0x25;		//LEFT ARROW key
	mKeyValMap["UP"].push_back(VK_UP);// 0x26;		//UP ARROW key
	mKeyValMap["RIGHT"].push_back(VK_RIGHT);// 0x27;		//RIGHT ARROW key
	mKeyValMap["DOWN"].push_back(VK_DOWN);// 0x28;		//DOWN ARROW key

	mKeyValMap["SELECT"].push_back(VK_SELECT);// 0x29;		//SELECT key
	mKeyValMap["PRINT"].push_back(VK_PRINT);// 0x2A;		//PRINT key
	mKeyValMap["EXECUTE"].push_back(VK_EXECUTE);// 0x2B;		//EXECUTE key
	mKeyValMap["SNAPSHOT"].push_back(VK_SNAPSHOT);// 0x2C;		//PRINT SCREEN key
	mKeyValMap["INSERT"].push_back(VK_INSERT);// 0x2D;		//INS key
	mKeyValMap["DELETE"].push_back(VK_DELETE);// 0x2E;		//DEL key
	mKeyValMap["HELP"].push_back(VK_HELP);// 0x2F;		//HELP key

	mKeyValMap["0"].push_back(0x30);		//0 key
	mKeyValMap["1"].push_back(0x31);		//1 key
	mKeyValMap["2"].push_back(0x32);		//2 key
	mKeyValMap["3"].push_back(0x33);		//3 key
	mKeyValMap["4"].push_back(0x34);		//4 key
	mKeyValMap["5"].push_back(0x35);		//5 key
	mKeyValMap["6"].push_back(0x36);		//6 key
	mKeyValMap["7"].push_back(0x37);		//7 key
	mKeyValMap["8"].push_back(0x38);		//8 key
	mKeyValMap["9"].push_back(0x39);		//9 key

	mKeyValMap["a"].push_back(0x41);		//A key
	mKeyValMap["A"].push_back(VK_SHIFT);
	mKeyValMap["A"].push_back(0x41);

	mKeyValMap["b"].push_back(0x42);		//B key
	mKeyValMap["B"].push_back(VK_SHIFT);
	mKeyValMap["B"].push_back(0x42);

	mKeyValMap["c"].push_back(0x43);		//C key
	mKeyValMap["C"].push_back(VK_SHIFT);
	mKeyValMap["C"].push_back(0x43);

	mKeyValMap["d"].push_back(0x44);		//D key
	mKeyValMap["D"].push_back(VK_SHIFT);
	mKeyValMap["D"].push_back(0x44);

	mKeyValMap["e"].push_back(0x45);		//E key
	mKeyValMap["E"].push_back(VK_SHIFT);
	mKeyValMap["E"].push_back(0x45);

	mKeyValMap["f"].push_back(0x46);		//F key
	mKeyValMap["F"].push_back(VK_SHIFT);
	mKeyValMap["F"].push_back(0x46);

	mKeyValMap["g"].push_back(0x47);		//G key
	mKeyValMap["G"].push_back(VK_SHIFT);
	mKeyValMap["G"].push_back(0x47);

	mKeyValMap["h"].push_back(0x48);		//H key
	mKeyValMap["H"].push_back(VK_SHIFT);
	mKeyValMap["H"].push_back(0x48);

	mKeyValMap["i"].push_back(0x49);		//I key
	mKeyValMap["I"].push_back(VK_SHIFT);
	mKeyValMap["I"].push_back(0x49);

	mKeyValMap["j"].push_back(0x4A);		//J key
	mKeyValMap["J"].push_back(VK_SHIFT);
	mKeyValMap["J"].push_back(0x4A);

	mKeyValMap["k"].push_back(0x4B);		//K key
	mKeyValMap["K"].push_back(VK_SHIFT);
	mKeyValMap["K"].push_back(0x4B);

	mKeyValMap["l"].push_back(0x4C);		//L key
	mKeyValMap["L"].push_back(VK_SHIFT);
	mKeyValMap["L"].push_back(0x4C);

	mKeyValMap["m"].push_back(0x4D);		//M key
	mKeyValMap["M"].push_back(VK_SHIFT);
	mKeyValMap["M"].push_back(0x4D);

	mKeyValMap["n"].push_back(0x4E);		//N key
	mKeyValMap["N"].push_back(VK_SHIFT);
	mKeyValMap["N"].push_back(0x4E);

	mKeyValMap["o"].push_back(0x4F);		//O key
	mKeyValMap["O"].push_back(VK_SHIFT);
	mKeyValMap["O"].push_back(0x4F);

	mKeyValMap["p"].push_back(0x50);		//P key
	mKeyValMap["P"].push_back(VK_SHIFT);
	mKeyValMap["P"].push_back(0x50);

	mKeyValMap["q"].push_back(0x51);		//Q key
	mKeyValMap["Q"].push_back(VK_SHIFT);
	mKeyValMap["Q"].push_back(0x51);

	mKeyValMap["r"].push_back(0x52);		//R key
	mKeyValMap["R"].push_back(VK_SHIFT);
	mKeyValMap["R"].push_back(0x52);

	mKeyValMap["s"].push_back(0x53);		//S key
	mKeyValMap["S"].push_back(VK_SHIFT);
	mKeyValMap["S"].push_back(0x53);

	mKeyValMap["t"].push_back(0x54);		//T key
	mKeyValMap["T"].push_back(VK_SHIFT);
	mKeyValMap["T"].push_back(0x54);

	mKeyValMap["u"].push_back(0x55);		//U key
	mKeyValMap["U"].push_back(VK_SHIFT);
	mKeyValMap["U"].push_back(0x55);

	mKeyValMap["v"].push_back(0x56);		//V key
	mKeyValMap["V"].push_back(VK_SHIFT);
	mKeyValMap["V"].push_back(0x56);

	mKeyValMap["w"].push_back(0x57);		//W key
	mKeyValMap["W"].push_back(VK_SHIFT);
	mKeyValMap["W"].push_back(0x57);

	mKeyValMap["x"].push_back(0x58);		//X key
	mKeyValMap["X"].push_back(VK_SHIFT);
	mKeyValMap["X"].push_back(0x58);

	mKeyValMap["y"].push_back(0x59);		//Y key
	mKeyValMap["Y"].push_back(VK_SHIFT);
	mKeyValMap["Y"].push_back(0x59);

	mKeyValMap["z"].push_back(0x5A);		//Z key
	mKeyValMap["Z"].push_back(VK_SHIFT);
	mKeyValMap["Z"].push_back(0x5A);

	mKeyValMap["LWIN"].push_back(VK_LWIN);// 0x5B;		//Left Windows key(Natural keyboard)
	mKeyValMap["RWIN"].push_back(VK_RWIN);// 0x5C;		//Right Windows key(Natural keyboard)
	mKeyValMap["APPS"].push_back(VK_APPS);// 0x5D;		//Applications key(Natural keyboard)
	mKeyValMap["SLEEP"].push_back(VK_SLEEP);// 0x5F;		//Computer Sleep key

	mKeyValMap["NUMPAD0"].push_back(VK_NUMPAD0);// 0x60;		//Numeric keypad 0 key
	mKeyValMap["NUMPAD1"].push_back(VK_NUMPAD1);// 0x61;		//Numeric keypad 1 key
	mKeyValMap["NUMPAD2"].push_back(VK_NUMPAD2);// 0x62;		//Numeric keypad 2 key
	mKeyValMap["NUMPAD3"].push_back(VK_NUMPAD3);// 0x63;		//Numeric keypad 3 key
	mKeyValMap["NUMPAD4"].push_back(VK_NUMPAD4);// 0x64;		//Numeric keypad 4 key
	mKeyValMap["NUMPAD5"].push_back(VK_NUMPAD5);// 0x65;		//Numeric keypad 5 key
	mKeyValMap["NUMPAD6"].push_back(VK_NUMPAD6);// 0x66;		//Numeric keypad 6 key
	mKeyValMap["NUMPAD7"].push_back(VK_NUMPAD7);// 0x67;		//Numeric keypad 7 key
	mKeyValMap["NUMPAD8"].push_back(VK_NUMPAD8);// 0x68;		//Numeric keypad 8 key
	mKeyValMap["NUMPAD9"].push_back(VK_NUMPAD9);// 0x69;		//Numeric keypad 9 key
	mKeyValMap["MULTIPLY"].push_back(VK_MULTIPLY);// 0x6A;		//Multiply key
	mKeyValMap["*"].push_back(VK_MULTIPLY);
	mKeyValMap["ADD"].push_back(VK_ADD);// 0x6B;		//Add key
	mKeyValMap["+"].push_back(VK_ADD);
	mKeyValMap["SEPARATOR"].push_back(VK_SEPARATOR);// 0x6C;		//Separator key
	mKeyValMap["SUBTRACT"].push_back(VK_SUBTRACT);// 0x6D;		//Subtract key
	mKeyValMap["-"].push_back(VK_SUBTRACT);
	mKeyValMap["DECIMAL"].push_back(VK_DECIMAL);// 0x6E;		//Decimal key
	mKeyValMap["."].push_back(VK_DECIMAL);
	mKeyValMap["DIVIDE"].push_back(VK_DIVIDE);// 0x6F;		//Divide key
	mKeyValMap["/"].push_back(VK_DIVIDE);

	mKeyValMap["F1"].push_back(VK_F1);// 0x70;		//F1 key
	mKeyValMap["F2"].push_back(VK_F2);// 0x71;		//F2 key
	mKeyValMap["F3"].push_back(VK_F3);// 0x72;		//F3 key
	mKeyValMap["F4"].push_back(VK_F4);// 0x73;		//F4 key
	mKeyValMap["F5"].push_back(VK_F5);// 0x74;		//F5 key
	mKeyValMap["F6"].push_back(VK_F6);// 0x75;		//F6 key
	mKeyValMap["F7"].push_back(VK_F7);// 0x76;		//F7 key
	mKeyValMap["F8"].push_back(VK_F8);// 0x77;		//F8 key
	mKeyValMap["F9"].push_back(VK_F9);// 0x78;		//F9 key
	mKeyValMap["F10"].push_back(VK_F10);// 0x79;		//F10 key
	mKeyValMap["F11"].push_back(VK_F11);// 0x7A;		//F11 key
	mKeyValMap["F12"].push_back(VK_F12);// 0x7B;		//F12 key
	mKeyValMap["F13"].push_back(VK_F13);// 0x7C;		//F13 key
	mKeyValMap["F14"].push_back(VK_F14);// 0x7D;		//F14 key
	mKeyValMap["F15"].push_back(VK_F15);// 0x7E;		//F15 key
	mKeyValMap["F16"].push_back(VK_F16);// 0x7F;		//F16 key
	mKeyValMap["F17"].push_back(VK_F17);// 0x80;		//F17 key
	mKeyValMap["F18"].push_back(VK_F18);// 0x81;		//F18 key
	mKeyValMap["F19"].push_back(VK_F19);// 0x82;		//F19 key
	mKeyValMap["F20"].push_back(VK_F20);// 0x83;		//F20 key
	mKeyValMap["F21"].push_back(VK_F21);// 0x84;		//F21 key
	mKeyValMap["F22"].push_back(VK_F22);// 0x85;		//F22 key
	mKeyValMap["F23"].push_back(VK_F23);// 0x86;		//F23 key
	mKeyValMap["F24"].push_back(VK_F24);// 0x87;		//F24 key

	mKeyValMap["NUMLOCK"].push_back(VK_NUMLOCK);// 0x90;		//NUM LOCK key
	mKeyValMap["SCROLL"].push_back(VK_SCROLL);// 0x91;		//SCROLL LOCK key
	mKeyValMap["SCROLLLOCK"].push_back(VK_SCROLL);// 0x91;
											 //iVal = 0x92 - 96;	//OEM specific
	mKeyValMap["LSHIFT"].push_back(VK_LSHIFT);// 0xA0;		//Left SHIFT key
	mKeyValMap["RSHIFT"].push_back(VK_RSHIFT);// 0xA1;		//Right SHIFT key
	mKeyValMap["LCONTROL"].push_back(VK_LCONTROL);// 0xA2;		//Left CONTROL key
	mKeyValMap["LCTRL"].push_back(VK_LCONTROL);// 0xA2;		//Left CONTROL key
	mKeyValMap["RCONTROL"].push_back(VK_RCONTROL);// 0xA3;		//Right CONTROL key
	mKeyValMap["RCTRL"].push_back(VK_RCONTROL);// 0xA3;		//Right CONTROL key
	mKeyValMap["LMENU"].push_back(VK_LMENU);// 0xA4;		//Left MENU key
	mKeyValMap["LALT"].push_back(VK_LMENU);// 0xA4;
	mKeyValMap["RMENU"].push_back(VK_RMENU);// 0xA5;		//Right MENU key
	mKeyValMap["RALT"].push_back(VK_RMENU);// 0xA5;

	mKeyValMap["BROWSER_BACK"].push_back(VK_BROWSER_BACK);// 0xA6;		//Browser Back key
	mKeyValMap["BROWSER_FORWARD"].push_back(VK_BROWSER_FORWARD);// 0xA7;		//Browser Forward key
	mKeyValMap["BROWSER_REFRESH"].push_back(VK_BROWSER_REFRESH);// 0xA8;		//Browser Refresh key
	mKeyValMap["BROWSER_STOP"].push_back(VK_BROWSER_STOP);// 0xA9;		//Browser Stop key
	mKeyValMap["BROWSER_SEARCH"].push_back(VK_BROWSER_SEARCH);// 0xAA;		//Browser Search key
	mKeyValMap["BROWSER_FAVORITES"].push_back(VK_BROWSER_FAVORITES);// 0xAB;		//Browser Favorites key
	mKeyValMap["BROWSER_HOME"].push_back(VK_BROWSER_HOME);// 0xAC;		//Browser Start and Home key

	mKeyValMap["VOLUME_MUTE"].push_back(VK_VOLUME_MUTE);// 0xAD;		//Volume Mute key
	mKeyValMap["VOLUME_DOWN"].push_back(VK_VOLUME_DOWN);// 0xAE;		//Volume Down key
	mKeyValMap["VOLUME_UP"].push_back(VK_VOLUME_UP);// 0xAF;		//Volume Up key

	mKeyValMap["MEDIA_NEXT_TRACK"].push_back(VK_MEDIA_NEXT_TRACK);// 0xB0;		//Next Track key
	mKeyValMap["MEDIA_PREV_TRACK"].push_back(VK_MEDIA_PREV_TRACK);// 0xB1;		//Previous Track key
	mKeyValMap["MEDIA_STOP"].push_back(VK_MEDIA_STOP);// 0xB2;		//Stop Media key
	mKeyValMap["MEDIA_PLAY_PAUSE"].push_back(VK_MEDIA_PLAY_PAUSE);// 0xB3;		//Play / Pause Media key

	mKeyValMap["LAUNCH_MAIL"].push_back(VK_LAUNCH_MAIL);// 0xB4;		//Start Mail key
	mKeyValMap["LAUNCH_MEDIA_SELECT"].push_back(VK_LAUNCH_MEDIA_SELECT);// 0xB5;		//Select Media key
	mKeyValMap["LAUNCH_APP1"].push_back(VK_LAUNCH_APP1);// 0xB6;		//Start Application 1 key
	mKeyValMap["LAUNCH_APP2"].push_back(VK_LAUNCH_APP2);// 0xB7;		//Start Application 2 key

	mKeyValMap["OEM_1"].push_back(VK_OEM_1);// 0xBA;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the ';:' key
	mKeyValMap["OEM_PLUS"].push_back(VK_OEM_PLUS);// 0xBB;		//For any country / region, the '+' key
	mKeyValMap["OEM_COMMA"].push_back(VK_OEM_COMMA);// 0xBC;		//For any country / region, the ',' key
	mKeyValMap["OEM_MINUS"].push_back(VK_OEM_MINUS);// 0xBD;		//For any country / region, the '-' key
	mKeyValMap["OEM_PERIOD"].push_back(VK_OEM_PERIOD);// 0xBE;		//For any country / region, the '.' key
	mKeyValMap["OEM_2"].push_back(VK_OEM_2);// 0xBF;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the '/?' key
	mKeyValMap["OEM_3"].push_back(VK_OEM_3);// 0xC0;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the '`~' key
	mKeyValMap["OEM_4"].push_back(VK_OEM_4);// 0xDB;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the '[{' key
	mKeyValMap["OEM_5"].push_back(VK_OEM_5);// 0xDC;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the '\|' key
	mKeyValMap["OEM_6"].push_back(VK_OEM_6);// 0xDD;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the ']}' key
	mKeyValMap["OEM_7"].push_back(VK_OEM_7);// 0xDE;		//Used for miscellaneous characters; it can vary by keyboard.For the US standard keyboard, the 'single-quote/double-quote' key
	mKeyValMap["OEM_8"].push_back(VK_OEM_8);// 0xDF;		//Used for miscellaneous characters; it can vary by keyboard.
										   //iVal = 0xE1;		//OEM specific
	mKeyValMap["OEM_102"].push_back(VK_OEM_102);// 0xE2;		//Either the angle bracket key or the backslash key on the RT 102 - key keyboard" == strKey)
											   //iVal = 0xE3 - E4;		//OEM specific
	mKeyValMap["PROCESSKEY"].push_back(VK_PROCESSKEY);// 0xE5;		//IME PROCESS key
													 //iVal = 0xE6;		//OEM specific
	mKeyValMap["PACKET"].push_back(VK_PACKET);// 0xE7;		//Used to pass Unicode characters as if they were keystrokes.The if ("PACKET key is the low word of a 32 - bit Virtual Key value used for non - keyboard input methods.For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP
											 //iVal = 0xE9 - F5;		//OEM specific
	mKeyValMap["ATTN"].push_back(VK_ATTN);// 0xF6;		//Attn key
	mKeyValMap["CRSEL"].push_back(VK_CRSEL);// 0xF7;		//CrSel key
	mKeyValMap["EXSEL"].push_back(VK_EXSEL);// 0xF8;		//ExSel key
	mKeyValMap["EREOF"].push_back(VK_EREOF);// 0xF9;		//Erase EOF key
	mKeyValMap["PLAY"].push_back(VK_PLAY);// 0xFA;		//Play key
	mKeyValMap["ZOOM"].push_back(VK_ZOOM);// 0xFB;		//Zoom key
	mKeyValMap["NONAME"].push_back(VK_NONAME);// 0xFC;		//Reserved
	mKeyValMap["PA1"].push_back(VK_PA1);// 0xFD;		//PA1 key
	mKeyValMap["OEM_CLEAR"].push_back(VK_OEM_CLEAR);// 0xFE;		//Clear key
}

bool SysCtrl::GetKeyVal(QString strKey, std::vector<int>& keysVec)
{
	return GetKeyVal(strKey.toUtf8().toStdString(), keysVec);
}

bool SysCtrl::GetKeyVal(std::string strKey, std::vector<int>& keysVec)
{
	if (mKeyValMap.empty())
	{
		InitKeyValMap();
	}
	auto itFind = mKeyValMap.find(strKey);
	if (itFind == mKeyValMap.end())
	{
		return false;
	}
	for each (auto it in itFind->second)
	{
		keysVec.push_back(it);
	}

	return true;
}

